/**
 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
 * Licensed under the LGPL or a commercial license.
 * For LGPL see License.txt in the project root for license information.
 * For commercial licenses see https://www.tiny.cloud/
 *
 * Version: 5.6.2 (2020-12-08)
 */
(function () {
    'use strict';

    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');

    var global$1 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');

    var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');

    var allowHtmlInNamedAnchor = function (editor) {
        return editor.getParam('allow_html_in_named_anchor', false, 'boolean');
    };

    var namedAnchorSelector = 'a:not([href])';
    var isEmptyString = function (str) {
        return !str;
    };
    var getIdFromAnchor = function (elm) {
        var id = elm.getAttribute('id') || elm.getAttribute('name');
        return id || '';
    };
    var isAnchor = function (elm) {
        return elm && elm.nodeName.toLowerCase() === 'a';
    };
    var isNamedAnchor = function (elm) {
        return isAnchor(elm) && !elm.getAttribute('href') && getIdFromAnchor(elm) !== '';
    };
    var isEmptyNamedAnchor = function (elm) {
        return isNamedAnchor(elm) && !elm.firstChild;
    };

    var removeEmptyNamedAnchorsInSelection = function (editor) {
        var dom = editor.dom;
        global$1(dom).walk(editor.selection.getRng(), function (nodes) {
            global$2.each(nodes, function (node) {
                if (isEmptyNamedAnchor(node)) {
                    dom.remove(node, false);
                }
            });
        });
    };
    var isValidId = function (id) {
        return /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
    };
    var getNamedAnchor = function (editor) {
        return editor.dom.getParent(editor.selection.getStart(), namedAnchorSelector);
    };
    var getId = function (editor) {
        var anchor = getNamedAnchor(editor);
        if (anchor) {
            return getIdFromAnchor(anchor);
        } else {
            return '';
        }
    };
    var createAnchor = function (editor, id) {
        editor.undoManager.transact(function () {
            if (!allowHtmlInNamedAnchor(editor)) {
                editor.selection.collapse(true);
            }
            if (editor.selection.isCollapsed()) {
                editor.insertContent(editor.dom.createHTML('a', {id: id}));
            } else {
                removeEmptyNamedAnchorsInSelection(editor);
                editor.formatter.remove('namedAnchor', null, null, true);
                editor.formatter.apply('namedAnchor', {value: id});
                editor.addVisual();
            }
        });
    };
    var updateAnchor = function (editor, id, anchorElement) {
        anchorElement.removeAttribute('name');
        anchorElement.id = id;
        editor.addVisual();
        editor.undoManager.add();
    };
    var insert = function (editor, id) {
        var anchor = getNamedAnchor(editor);
        if (anchor) {
            updateAnchor(editor, id, anchor);
        } else {
            createAnchor(editor, id);
        }
        editor.focus();
    };

    var insertAnchor = function (editor, newId) {
        if (!isValidId(newId)) {
            editor.windowManager.alert('Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
            return false;
        } else {
            insert(editor, newId);
            return true;
        }
    };
    var open = function (editor) {
        var currentId = getId(editor);
        editor.windowManager.open({
            title: 'Anchor',
            size: 'normal',
            body: {
                type: 'panel',
                items: [{
                    name: 'id',
                    type: 'input',
                    label: 'ID',
                    placeholder: 'example'
                }]
            },
            buttons: [
                {
                    type: 'cancel',
                    name: 'cancel',
                    text: 'Cancel'
                },
                {
                    type: 'submit',
                    name: 'save',
                    text: 'Save',
                    primary: true
                }
            ],
            initialData: {id: currentId},
            onSubmit: function (api) {
                if (insertAnchor(editor, api.getData().id)) {
                    api.close();
                }
            }
        });
    };

    var register = function (editor) {
        editor.addCommand('mceAnchor', function () {
            open(editor);
        });
    };

    var isNamedAnchorNode = function (node) {
        return node && isEmptyString(node.attr('href')) && !isEmptyString(node.attr('id') || node.attr('name'));
    };
    var isEmptyNamedAnchorNode = function (node) {
        return isNamedAnchorNode(node) && !node.firstChild;
    };
    var setContentEditable = function (state) {
        return function (nodes) {
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                if (isEmptyNamedAnchorNode(node)) {
                    node.attr('contenteditable', state);
                }
            }
        };
    };
    var setup = function (editor) {
        editor.on('PreInit', function () {
            editor.parser.addNodeFilter('a', setContentEditable('false'));
            editor.serializer.addNodeFilter('a', setContentEditable(null));
        });
    };

    var registerFormats = function (editor) {
        editor.formatter.register('namedAnchor', {
            inline: 'a',
            selector: namedAnchorSelector,
            remove: 'all',
            split: true,
            deep: true,
            attributes: {id: '%value'},
            onmatch: function (node, _fmt, _itemName) {
                return isNamedAnchor(node);
            }
        });
    };

    var register$1 = function (editor) {
        editor.ui.registry.addToggleButton('anchor', {
            icon: 'bookmark',
            tooltip: 'Anchor',
            onAction: function () {
                return editor.execCommand('mceAnchor');
            },
            onSetup: function (buttonApi) {
                return editor.selection.selectorChangedWithUnbind('a:not([href])', buttonApi.setActive).unbind;
            }
        });
        editor.ui.registry.addMenuItem('anchor', {
            icon: 'bookmark',
            text: 'Anchor...',
            onAction: function () {
                return editor.execCommand('mceAnchor');
            }
        });
    };

    function Plugin() {
        global.add('anchor', function (editor) {
            setup(editor);
            register(editor);
            register$1(editor);
            editor.on('PreInit', function () {
                registerFormats(editor);
            });
        });
    }

    Plugin();

}());
